#include "matrix.h"

void matrix_multiply(Matrix_T* local_A, Matrix_T* local_B, Matrix_T* local_C)
{
    int i,j,k;
    double element;
    assert(local_A->col == local_B->row);
    for(i=0;i<local_A->row;i++){
        for(j=0;j<local_B->col;j++){
            element=0.0;
            for(k=0;k<local_A->col;k++){
                element += local_A->matrix[i*local_A->col+k]*
                    local_B->matrix[k*local_B->col+j];
            }
            local_C->matrix[local_C->col*i+j] += element;
        }
    }
}

void matrix_allocate(Matrix_T* mat, int row, int col)
{
    mat->row = row;
    mat->col = col;
    mat->matrix = (double*)malloc(row*col*sizeof(double));
}



void matrix_free(Matrix_T* mat)
{
    free(mat->matrix);
}


void matrix_set_to_zero(Matrix_T* mat)
{
    int i;
    for(i=0;i<mat->row*mat->col;i++){
        mat->matrix[i] = 0.0;
    }
}

void matrix_set_to_one(Matrix_T* mat)
{
    int i;
    for(i=0;i<mat->row*mat->col;i++){
        mat->matrix[i] = 1.0;
    }
}

void matrix_set_to_identity(Matrix_T* mat)
{
    int i;
    for(i=0;i<mat->row;i++){
        mat->matrix[i*mat->col+i] = 1.0;
    }
}

void matrix_set(Matrix_T* mat,double init)
{
    int i;
    for(i=0;i<mat->row*mat->col;i++){
        mat->matrix[i] = init++;
    }
}

void matrix_print(Matrix_T* mat)
{
    int i,j;
    for(i=0;i<mat->row;i++){
        for(j=0;j<mat->col;j++){
            printf("%10.2f ",mat->matrix[i*mat->col+j]);
        }
        printf("\n");
    }
}

void matrix_rearrange(Matrix_T* mat, int M, int N)
{
    Matrix_T temp_C;
    int I,J,i,j,m,n;
    I = mat->row/M;
    J = mat->col/N;
    matrix_allocate(&temp_C,mat->row,mat->col);
    for(i=0;i<I;i++){
        for(j=0;j<J;j++){
            for(m=0;m<M;m++){
                for(n=0;n<N;n++){
                    temp_C.matrix[i*M*J*N+j*N+m*J*N+n] = 
                        mat->matrix[i*M*N*J+j*M*N+m*N+n];
                }
            }
        }
    }
    free(mat->matrix);
    mat->matrix = temp_C.matrix;
}
